package com.sikaryofficial.auth.controller;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import com.sikaryofficial.auth.config.HiSMKAuthConfig;
import com.sikaryofficial.auth.constant.AuthConstants;
import com.sikaryofficial.auth.controller.domain.AuthLoginReq;
import com.sikaryofficial.auth.form.RegisterH5Body;
import com.sikaryofficial.auth.service.SysLoginService;
import com.sikaryofficial.auth.service.UserService;
import com.sikaryofficial.common.core.constant.RegisterTypeEnum;
import com.sikaryofficial.common.core.constant.SecurityConstants;
import com.sikaryofficial.common.core.domain.R;
import com.sikaryofficial.common.core.exception.ServiceException;
import com.sikaryofficial.common.core.utils.ServletUtils;
import com.sikaryofficial.common.core.utils.StringUtils;
import com.sikaryofficial.system.api.util.NickNameGen;
import com.xkcoding.justauth.AuthRequestFactory;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @author : qinjinyuan
 * @desc : TODO  请填写你的功能描述
 * @date : 2024/05/23 20:20
 */
@Slf4j
@RestController
@RequestMapping("/oauth")
public class ThirdLoginController {
    @Resource
    private AuthRequestFactory factory;
    @Resource
    private UserService userService;
    @Autowired
    private SysLoginService sysLoginService;
    @Resource
    private HiSMKAuthConfig authConfig;
    @GetMapping
    public List<String> list() {
        return factory.oauthList();
    }

    @GetMapping("/login/{source}")
    public void login(@PathVariable String source, HttpServletResponse response) throws IOException {
        AuthRequest authRequest = factory.get(source);
        String state = AuthStateUtils.createState();
        response.sendRedirect(authRequest.authorize(state));
        log.info("third login--------->>state:{}", state);
    }

    @PostMapping("/callback/{source}")
    public R<Map<String, Object>> callback(@PathVariable String source, @RequestBody AuthLoginReq authUser) {
        log.info("【callback param】= {}", JSONUtil.toJsonStr(authUser));
        authUser.setSource(source);
        // 1、保存为缓存数据
        userService.save(authUser);
        // 2、注册或者登录
        return registerAndLogin(authUser);
    }

    @RequestMapping("/callbackTest/{source}")
    public R<Map<String, Object>> callback1(@PathVariable String source, AuthLoginReq callback) {
        // TODO:  用户登录 或者 入库 ，解绑  AuthResponse.data的数据结构不一样，还需要做定制处理
        // 下面的模拟测试代码
        AuthResponse<AuthLoginReq> response = new AuthResponse<>();
        response.setCode(AuthResponseStatus.SUCCESS.getCode());
        response.setData(buildAuthUserData());
        response.setMsg("success");
        if (response.ok()) {
            // 1、保存为缓存数据
            userService.save(response.getData());
            // 2、注册或者登录
            return registerAndLogin(response.getData());
        }
        throw new ServiceException("login error");
    }

    private AuthLoginReq buildAuthUserData() {
        AuthLoginReq user = new AuthLoginReq();
        user.setFirstName("first");
        user.setLastName("last");
        user.setUuid("12209655791034855");
        user.setEmail("jsjxqjy55@126.com");
        user.setAvatar("https://platform-lookaside.fbsbx.com/platform/profilepic/?asid=122096557910348343&width=400&ext=1719975763&hash=AbYJJuxD7G7t5Lw3CN95pK7I");
        user.setSource("FACEBOOK");
        user.setUsername("Ske QJY");
        user.setNickname("hi Ske");
        AuthToken token = new AuthToken();
        user.setToken(token);
        token.setTokenType("bearer");
        token.setAccessToken("EAANtZAVBurVMBO0RoYEMzyDp0a9JHhFWQ1WmvcsY6ANt8eJi9bnC7oAwem7uLzaHOlOPZAJ3y0JIFo8FDxU9mpPQIW4ltG6UMc4ZBpsSX08sBYCCwLVnIX4PzBxeFl7PsndHNTswzrxlESJZBBcyR3FN3ca1xPDz6aXRvRgrnx8QzB1CwUJTTE0zZCg4pBxJYxy1t6PJjBcLx8NrX7j8ZAt2TXthZC03ZBBIUrWBdJzH7BvjZA6s5MeLU");
        token.setExpireIn(5183998);
        token.setRefreshTokenExpireIn(0);
        return user;
    }

    private R<Map<String, Object>> registerAndLogin(AuthLoginReq authUser) {
        // 注册登录公共方法
        RegisterH5Body registerBody = new RegisterH5Body();
        registerBody.setBrandNo(ServletUtils.getRequest().getHeader(SecurityConstants.BRAND_KEY));
        registerBody.setSource(authUser.getSource());
        registerBody.setFirstName(authUser.getFirstName());
        registerBody.setLastName(authUser.getLastName());
        registerBody.setAge(AuthConstants.DEFAULT_USER_AGE);
        registerBody.setRegisterType(RegisterTypeEnum.THIRD_LOGIN.getCode());

        /**
         * 1、判定 第三方用户表是否存在 认证用户
         * 2、存在，则直接登录
         * 3、否则进行注册并登录
         */
        String email = authUser.getEmail();
        String username;
        if(CharSequenceUtil.isBlank(email)){
            username = sysLoginService.getUserNameByUuid(authUser.getUuid());
            log.error("username1:{}",username);
            log.error("the third user email is null");
        }else{
            registerBody.setEmailAddress(email);
            // 如果邮箱不为空,则通过邮箱查询对应用户名
            username = sysLoginService.getUserNameByEmail(email);
            log.error("username2:{}",username);
        }
        buildNickName(registerBody, username);
        Map<String, Object> result;
        if (StringUtils.isBlank(username)) {
            // 注册并登录
            result = sysLoginService.registerAndLoginForThird(registerBody, authUser);
            result.put(AuthConstants.HAS_REGISTER_KEY, true);
        } else {
            // 登录
            result = sysLoginService.loginOnlyForH5(username);
            result.put(AuthConstants.HAS_REGISTER_KEY, false);
        }
        result.put("email", email);
        return R.ok(result);
    }

    private void buildNickName(RegisterH5Body registerBody, String username) {
        // 增加昵称设值
        String nickName = "";
        try{
            nickName = NickNameGen.generateNicknameFromEmailPrefix(username);
            registerBody.setNickName(nickName);
        }catch (Exception e){
            log.error("nickname build error");
        }
    }
}
